#include<stdbool.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<signal.h>
#include<wordexp.h>
#include"decomposition.h"


bool arriere_plan=false;        // True si la tâche doit s'exécuter en arrière plan.

char redirection='0';           // '<' ou '>' s'il y a une redirection.
char fichier_redirection[100];  // Contient le nom du fichier de redirection.

int nb_commandes=1;             // Contient le nombre de commandes (nombre de pipes + 1).

char* commandes[100];           // Tableau des différentes commandes (une seule s'il n'y a pas de pipe).
char* mots[100][100];           // Tableau des mots des différentes commandes.
int nb_mots[100];               // Nombre de mots des différentes commandes.


void decomposition()
{
  bool modif1=false, modif2=false;
  arriere_plan=false;
  redirection='0';
  nb_commandes=1;
  int k=0;


  char input[1000];
  while (1) {
    if (fgets(input,sizeof(input)-1,stdin)) break; /* lecture OK */
    if (feof(stdin)) {
      /* vrai fin */
      printf("\n");
      exit(0);
    }
   }
  
  
  // 1. Détection du &.
  char* pch;
  pch=(char*) memchr(input, '&', strlen(input));
  if(pch!=NULL)
  {
    pch=strtok(input, "&");
    commandes[0]=malloc(strlen(pch)*sizeof(char));
    strcpy(commandes[0], pch);
    arriere_plan=true;
    modif1=true;
  }
  
  
  // 2. Détection du <.
  pch=(char*) memchr(input, '<', strlen(input));
  if(pch!=NULL)
  {
    pch=strtok(input, "<");
    commandes[0]=malloc(strlen(pch)*sizeof(char));
    strcpy(commandes[0], pch);
    
    // Récupération du nom de fichier dans pch.
    pch=strtok(NULL, "|");
    pch=strtok(pch, " ");
    if(pch[strlen(pch)-1]==10)
    {
      pch[strlen(pch)-1]='\0';
    }
    
    strcpy(fichier_redirection, pch);
    redirection='<';
    modif1=true;
  }
  
  
  // 3. Détection du >.
  pch=(char*) memchr(input, '>', strlen(input));
  if(pch!=NULL)
  {
    pch=strtok(input, ">");
    commandes[0]=malloc(strlen(pch)*sizeof(char));
    strcpy(commandes[0], pch);

    // Récupération du nom de fichier dans pch.
    pch=strtok(NULL, "|");
    pch=strtok(pch, " ");
    if(pch[strlen(pch)-1]==10)
    {
      pch[strlen(pch)-1]='\0';
    }
    
    strcpy(fichier_redirection, pch);
    redirection='>';
    modif1=true;
  }
  
  
  // 4. Détection du |.
  pch=(char*) memchr(input, '|', strlen(input));
  if(pch!=NULL)
  {
    nb_commandes=0;
    pch=strtok(input, "|");
    while(pch!=NULL)
    {
      commandes[nb_commandes]=malloc(strlen(pch)*sizeof(char));
      strcpy(commandes[nb_commandes], pch);
      nb_commandes++;
      pch=strtok(NULL, "|");
    }
    modif2=true;
  }
  
  
  if(!modif1 && !modif2)
  {
    commandes[0]=malloc(strlen(input)*sizeof(char));
    strcpy(commandes[0], input);
  }
  

  // 5. Décomposition des commandes en mots.
  for(k=0;k<nb_commandes;k++)
  {
    nb_mots[k]=0;
    pch=strtok(commandes[k], " ");
    while(pch!=NULL)
    {
      mots[k][nb_mots[k]]=malloc(strlen(pch)*sizeof(char));
      strcpy(mots[k][nb_mots[k]], pch);
      pch=strtok(NULL, " ");
      nb_mots[k]++;
    }
    if(mots[k][nb_mots[k]-1][0]=='\n')
    {
      nb_mots[k]--;
    }
    else if (!modif1 && k==nb_commandes-1)
    {
      int longueur=strlen(mots[k][nb_mots[k]-1]);
      mots[k][nb_mots[k]-1][longueur-1]='\0';
    }
    mots[k][nb_mots[k]]=NULL; // NULL nécessaire pour execvp.
  }
 

  // 6. Résolution du joker.
  for(k=0;k<nb_commandes;k++)
  {
    int i, j;
    for(i=0;i<nb_mots[k];i++)
    {
      pch=(char*) memchr(mots[k][i], '*', strlen(mots[k][i]));
      if(pch!=NULL)
      {
        wordexp_t res;
        res.we_offs=i;
        wordexp(mots[k][i], &res, WRDE_DOOFFS);
        for(j=nb_mots[k];j<nb_mots[k]-i;j--) // Décalage des mots de mots[k] de res.we_wordc cases.
        {
          mots[k][j+res.we_wordc-1]=mots[k][j];
        }
        unsigned int u;
        for(u=0;u<res.we_wordc;u++) // Ajout des nouveaux mots au tableau mots[k];
        {
          mots[k][u+i]=res.we_wordv[u+i];
        }
        nb_mots[k]=nb_mots[k]+res.we_wordc-1; // Mise à jour du nombre total de mots.
        //wordfree(&res); // Libération des éléments alloués par wordexp.
      }
    }
  }


  // Affichage du résultat de la décomposition de la ligne de commande.
  /*int i=0;
  if (arriere_plan)
  {
    printf("L'execution se fait en arriere plan.\n");
  }
  if (redirection=='<')
  {
    printf("L'entree est redirigee vers %s.\n", fichier_redirection);
  }
  if (redirection=='>')
  {
    printf("La sortie est redirigee vers %s.\n", fichier_redirection);
  }
  printf("Il y a %d commandes.\n\n", nb_commandes);
  for(k=0;k<nb_commandes;k++)
  {
    printf("Commande %d :\n", k+1);
    printf("Nombre de mots : %d.\n", nb_mots[k]);
    for(i=0;i<=nb_mots[k];i++)
    {
      printf("Mot %d : .%s.\n", i+1, mots[k][i]);
    }
    printf("\n");
  }*/
}

